package com.gitee.wsl.ext.base

val MINUS_ZERO_F = -0.0f

/**
 * The number of bits used to represent a `float` value.
 *
 * @since 1.5
 */
 
val Float.Companion.SIZE: Int
    get() = Float.SIZE_BITS

val Float.Companion.BYTES: Int
    get() = Float.SIZE_BYTES

/**
 * The number of bits in the significand of a `float` value.
 * This is the parameter N in section {@jls 4.2.3} of
 * <cite>The Java Language Specification</cite>.
 *
 * @since 19
 */

 val Float.Companion.PRECISION: Int
    get() = 24

/**
 * Maximum exponent a finite `float` variable may have.  It
 * is equal to the value returned by `Math.getExponent(Float.MAX_VALUE)`.
 *
 * @since 1.6
 */
val Float.Companion.MAX_EXPONENT: Int  // 127
    get() = (1 shl (SIZE - PRECISION - 1)) - 1

/**
 * Minimum exponent a normalized `float` variable may have.
 * It is equal to the value returned by `Math.getExponent(Float.MIN_NORMAL)`.
 *
 * @since 1.6
 */
val Float.Companion.MIN_EXPONENT: Int  // -126
    get() = 1 - MAX_EXPONENT

fun Float.Companion.intBitsToFloat(bits:Int) = fromBits(bits)

fun Float.Companion.floatToRawIntBits(value:Float) = value.toRawBits()

fun Float.Companion.isInfinite(value:Float) = value.isInfinite()

fun Float.Companion.isNaN(value:Float) = value.isNaN()

fun Float.Companion.isFinite(value:Float) = value.isFinite()


/**
 * This class contains additional constants documenting limits of the
 * `float` type.
 *
 * @author Joseph D. Darcy
 */
object FloatConsts {
    /**
     * The number of logical bits in the significand of a
     * `float` number, including the implicit bit.
     */
    val SIGNIFICAND_WIDTH: Int = Float.PRECISION

    /**
     * The exponent the smallest positive `float`
     * subnormal value would have if it could be normalized.
     */
    val MIN_SUB_EXPONENT: Int = Float.MIN_EXPONENT - (SIGNIFICAND_WIDTH - 1) // -149

    /**
     * Bias used in representing a `float` exponent.
     */
    val EXP_BIAS: Int = (1 shl (Float.SIZE - SIGNIFICAND_WIDTH - 1)) - 1 // 127

    /**
     * Bit mask to isolate the sign bit of a `float`.
     */
    val SIGN_BIT_MASK: Int = 1 shl (Float.SIZE - 1)

    /**
     * Bit mask to isolate the exponent field of a `float`.
     */
    val EXP_BIT_MASK: Int = ((1 shl (Float.SIZE - SIGNIFICAND_WIDTH)) - 1) shl (SIGNIFICAND_WIDTH - 1)

    /**
     * Bit mask to isolate the significand field of a `float`.
     */
    val SIGNIF_BIT_MASK: Int = (1 shl (SIGNIFICAND_WIDTH - 1)) - 1

    /**
     * Bit mask to isolate the magnitude bits (combined exponent and
     * significand fields) of a `float`.
     */
    val MAG_BIT_MASK: Int = EXP_BIT_MASK or SIGNIF_BIT_MASK

    init {
        // verify bit masks cover all bit positions and that the bit
        // masks are non-overlapping
        require(
            ((SIGN_BIT_MASK or EXP_BIT_MASK or SIGNIF_BIT_MASK) == 0.inv()) &&
                    (((SIGN_BIT_MASK and EXP_BIT_MASK) == 0) &&
                            ((SIGN_BIT_MASK and SIGNIF_BIT_MASK) == 0) &&
                            ((EXP_BIT_MASK and SIGNIF_BIT_MASK) == 0)) &&
                    ((SIGN_BIT_MASK or MAG_BIT_MASK) == 0.inv())
        )
    }
}